package cn.gov.pbc.tims.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.client.InterceptingAsyncClientHttpRequestFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import cn.gov.pbc.tims.entity.Dept;
import cn.gov.pbc.tims.entity.Jginfo;
import cn.gov.pbc.tims.entity.User;
import cn.gov.pbc.tims.service.CommonService;
import cn.gov.pbc.tims.service.UserService;
import cn.gov.pbc.tims.util.Operator;
import cn.gov.pbc.tims.util.PageData;
import cn.gov.pbc.tims.util.Result;

@Controller
@RequestMapping("/user")
public class UserController {
	@Autowired
	private Operator operator;
	@Autowired
	private SessionFactory sessionFactory;
	@Autowired
	private UserService userService;
	@Autowired
	private CommonService commonService;
	@Autowired 
	private ObjectMapper objectMapper;
	private static ArrayNode jgCache;
	private Session getCurrentSession() {
		return this.sessionFactory.getCurrentSession();
	}
	
	private List<Jginfo> getChildren(String pbcid){
 		Query<Jginfo> q = this.getCurrentSession().createQuery("from Jginfo where c1Id='A' and pbcId='"+pbcid+"'", Jginfo.class).setCacheable(true);
		List<Jginfo> Jginfos = q.getResultList();
		Query<Jginfo> q1 = this.getCurrentSession().createQuery("from Jginfo where c1Id='C' and pbcId='"+pbcid+"'", Jginfo.class).setCacheable(true);
		List<Jginfo> Jginfos1 = q1.getResultList();
		for(int i=0;i<Jginfos1.size();i++)
		{
			Jginfos.add(Jginfos1.get(i));
		}
		
		return Jginfos;
 	}
	private List<Jginfo> getChildrenPbc(String pbcid){
 		Query<Jginfo> q = this.getCurrentSession().createQuery("from Jginfo where c1Id='A' and pbcId='"+pbcid+"'", Jginfo.class).setCacheable(true);
		List<Jginfo> Jginfos = q.getResultList();	
		return Jginfos;
 	}
	
	
	private List<Dept> getChildrenDept(Integer deptId){
 		Query<Dept> q = this.getCurrentSession().createQuery("from Dept where  upDeptId='"+deptId+"'", Dept.class).setCacheable(true);
		List<Dept> Depts = q.getResultList();
		return Depts;
 	}
 	private boolean hasChildren(String pbcid){
 		return getChildren(pbcid).size()>0;
 	}
	
	//获得两层，自己和儿子,只返回两层人行单位数据，为了实现管理员只管理本级和下级管理员
			@RequestMapping(value="getmysonpbc",produces=MediaType.APPLICATION_JSON_VALUE)
			public @ResponseBody ArrayNode getmysonpbc() throws JsonProcessingException, IOException{
				ArrayNode jsonArray=objectMapper.createArrayNode();
				User op=operator.getUser();
				if(op==null) return jsonArray;
				String pbcid=op.getJgId();
				Query<Jginfo> q = this.getCurrentSession().createQuery("from Jginfo where jgId='"+pbcid+"'", Jginfo.class).setCacheable(true);
				Jginfo pbcinfo = q.getSingleResult();
				ObjectNode jsonObject=objectMapper.createObjectNode();
				jsonObject.set("id",objectMapper.convertValue(pbcid,JsonNode.class));
				jsonObject.set("text",objectMapper.convertValue(pbcinfo.getJgName(),JsonNode.class));
				jsonObject.set("state",objectMapper.convertValue("open",JsonNode.class));
				ArrayNode jsonArray1=objectMapper.createArrayNode();
				for(Jginfo Jginfo : getChildrenPbc(pbcid)){
					ObjectNode jo=objectMapper.createObjectNode();
					String id0 =  Jginfo.getJgId();
					jo.set("id",objectMapper.convertValue(id0,JsonNode.class));
					jo.set("text",objectMapper.convertValue(Jginfo.getJgName(),JsonNode.class));
					jo.set("state",objectMapper.convertValue("open",JsonNode.class));				
					jsonArray1.add(jo);
				}
				if(jsonArray1.size()>0){	
					jsonObject.set("children", jsonArray1);
				}
				jsonArray.add(jsonObject);
				return jsonArray;		
			}
			
			
			
			//人行单位树当前层的数据，前台点击哪个分支时，获取这个分支数据。这是为了给通讯录用的。
			@RequestMapping(value="getpbc",produces=MediaType.APPLICATION_JSON_VALUE)
			public @ResponseBody ArrayNode getpbc(String id) throws JsonProcessingException, IOException{
				ArrayNode jsonArray=objectMapper.createArrayNode();
				if(id==null) id="A1000111000031";//这是总行的id
				List<Jginfo> Jginfoss = getChildren(id);
				for(Jginfo Jginfo : Jginfoss){
					ObjectNode jsonObject=objectMapper.createObjectNode();
					String id0 =  Jginfo.getJgId();
					jsonObject.set("id",objectMapper.convertValue(id0,JsonNode.class));
					jsonObject.set("text",objectMapper.convertValue(Jginfo.getJgName(),JsonNode.class));
					
					if(id0.indexOf("A")!=-1)
					{
						jsonObject.set("state",objectMapper.convertValue(hasChildren(id0) ? "closed" : "open",JsonNode.class));
					}
					else
					{
						jsonObject.set("state",objectMapper.convertValue("open",JsonNode.class));
					}
					
					jsonArray.add(jsonObject);
				}
				//JsonNode jsonNode=objectMapper.readTree(new File(this.getClass().getResource("/json/pbc.json").getPath()));
				return jsonArray;
			}		
	
	//取出下级人行机构
	private String getPbcChildren(String pbcid) {
		String retstr = "'',";//防止县支行没下级单位时sql in 语句出错
		Query<Jginfo> q = this.getCurrentSession()
				.createQuery("from Jginfo where c1Id='A' and pbcId='" + pbcid + "'", Jginfo.class)
				.setCacheable(true);
		List<Jginfo> Jginfos = q.getResultList();
		for (Jginfo jg : Jginfos) {
			retstr += "'" + jg.getJgId() + "',";
		}
	
		return retstr+"''";//防止县支行没下级单位时sql in 语句出错
	}
	@RequestMapping(value="getJgDeptList")
	public @ResponseBody ArrayNode getDeptList(String  jgId) throws JsonProcessingException, IOException{
		ArrayNode jsonArray=objectMapper.createArrayNode();
		User op=operator.getUser();
		if(null==jgId)
			jgId=op.getJgId();
		Query<Dept> q = this.getCurrentSession().createQuery("from Dept where level='1'   and jgId= '" + jgId + "'", Dept.class).setCacheable(true);
		List<Dept> DeptLevel1 = q.getResultList();
		for (Dept dept:DeptLevel1)
		{
			ObjectNode jsonObject=objectMapper.createObjectNode();
			jsonObject.set("id",objectMapper.convertValue(dept.getId(),JsonNode.class));
			jsonObject.set("text",objectMapper.convertValue(dept.getDeptName(),JsonNode.class));
			jsonObject.set("state",objectMapper.convertValue("open",JsonNode.class));
			ArrayNode jsonArray1=objectMapper.createArrayNode();
			for(Dept deptlevel2 : getChildrenDept(dept.getId())){
				ObjectNode jo=objectMapper.createObjectNode();
				jo.set("id",objectMapper.convertValue(deptlevel2.getId(),JsonNode.class));
				jo.set("text",objectMapper.convertValue(deptlevel2.getDeptName(),JsonNode.class));
				jo.set("state",objectMapper.convertValue("open",JsonNode.class));				
				jsonArray1.add(jo);
			}
			if(jsonArray1.size()>0){	
				jsonObject.set("children", jsonArray1);
			}
			jsonArray.add(jsonObject);
		}
 
		return jsonArray;		
	}
	@RequestMapping(value="getL1DeptSubList")
	public @ResponseBody ArrayNode getL1DeptSubList(String  deptId) throws JsonProcessingException, IOException{
		ArrayNode jsonArray=objectMapper.createArrayNode();
		User op=operator.getUser();
		Integer id;
		if(null==deptId)
			id=op.getDeptId();
		else id=Integer.valueOf(deptId);
		Dept root=commonService.get(Dept.class, id);
		if(!root.getLevel().equals("1"))
		{
			root=commonService.get(Dept.class, root.getUpDeptId());
		}
		 
		ObjectNode jsonObject=objectMapper.createObjectNode();
		jsonObject.set("id",objectMapper.convertValue(root.getId(),JsonNode.class));
		jsonObject.set("text",objectMapper.convertValue(root.getDeptName(),JsonNode.class));
		jsonObject.set("state",objectMapper.convertValue("open",JsonNode.class));
		ArrayNode jsonArray1=objectMapper.createArrayNode();
		for(Dept deptlevel2 : getChildrenDept(root.getId())){
				ObjectNode jo=objectMapper.createObjectNode();
				jo.set("id",objectMapper.convertValue(deptlevel2.getId(),JsonNode.class));
				jo.set("text",objectMapper.convertValue(deptlevel2.getDeptName(),JsonNode.class));
				jo.set("state",objectMapper.convertValue("open",JsonNode.class));				
				jsonArray1.add(jo);
			}
			if(jsonArray1.size()>0){	
				jsonObject.set("children", jsonArray1);
			}
			jsonArray.add(jsonObject);
 
		return jsonArray;		
	}
	@RequestMapping(value="getDeptList")
	public @ResponseBody ArrayNode getDeptList() throws JsonProcessingException, IOException{
		ArrayNode jsonArray=objectMapper.createArrayNode();
		User op=operator.getUser();
		Query<Dept> q = this.getCurrentSession().createQuery("from Dept where level='1'", Dept.class).setCacheable(true);
		List<Dept> DeptLevel1 = q.getResultList();
		for (Dept dept:DeptLevel1)
		{
			ObjectNode jsonObject=objectMapper.createObjectNode();
			jsonObject.set("id",objectMapper.convertValue(dept.getId(),JsonNode.class));
			jsonObject.set("text",objectMapper.convertValue(dept.getDeptName(),JsonNode.class));
			jsonObject.set("state",objectMapper.convertValue("open",JsonNode.class));
			ArrayNode jsonArray1=objectMapper.createArrayNode();
			for(Dept deptlevel2 : getChildrenDept(dept.getId())){
				ObjectNode jo=objectMapper.createObjectNode();
				jo.set("id",objectMapper.convertValue(deptlevel2.getId(),JsonNode.class));
				jo.set("text",objectMapper.convertValue(deptlevel2.getDeptName(),JsonNode.class));
				jo.set("state",objectMapper.convertValue("open",JsonNode.class));				
				jsonArray1.add(jo);
			}
			if(jsonArray1.size()>0){	
				jsonObject.set("children", jsonArray1);
			}
			jsonArray.add(jsonObject);
		}
 
		return jsonArray;		
	}
	@RequestMapping(value="getDeptTree")
	public @ResponseBody ArrayNode getDeptTree(String  jgId) throws JsonProcessingException, IOException{
		ArrayNode jsonArray=objectMapper.createArrayNode();
		User op=operator.getUser();
		if(null==jgId)
			jgId=op.getJgId();
		Query<Dept> q = this.getCurrentSession().createQuery("from Dept where level='1'  and jgId= '" + jgId + "'", Dept.class).setCacheable(true);
		List<Dept> DeptLevel1 = q.getResultList();
		for (Dept dept:DeptLevel1)
		{
			ObjectNode jsonObject=objectMapper.createObjectNode();
			jsonObject.set("id",objectMapper.convertValue(dept.getId(),JsonNode.class));
			jsonObject.set("deptName",objectMapper.convertValue(dept.getDeptName(),JsonNode.class));
			jsonObject.set("level",objectMapper.convertValue(dept.getLevel(),JsonNode.class));
			jsonObject.set("jgId",objectMapper.convertValue(dept.getJgId(),JsonNode.class));
			jsonObject.set("state",objectMapper.convertValue("open",JsonNode.class));
			ArrayNode jsonArray1=objectMapper.createArrayNode();
			for(Dept deptlevel2 : getChildrenDept(dept.getId())){
				ObjectNode jo=objectMapper.createObjectNode();
				jo.set("id",objectMapper.convertValue(deptlevel2.getId(),JsonNode.class));
				jo.set("deptName",objectMapper.convertValue(deptlevel2.getDeptName(),JsonNode.class));
				jo.set("level",objectMapper.convertValue(deptlevel2.getLevel(),JsonNode.class));
				jo.set("jgId",objectMapper.convertValue(deptlevel2.getJgId(),JsonNode.class));
				jo.set("state",objectMapper.convertValue("open",JsonNode.class));			
				jsonArray1.add(jo);
			}
			if(jsonArray1.size()>0){	
				jsonObject.set("children", jsonArray1);
			}
			jsonArray.add(jsonObject);
		}
 
		return jsonArray;		
	}
	@RequestMapping(value="getDeptUsers" )
	public @ResponseBody List<User> getDeptUsers(String deptId) throws JsonProcessingException, IOException{
		 
 		String hql="from User where deptId=:deptId";
		Query  query = this.getCurrentSession().createQuery(hql, User.class).setCacheable(true);
		query.setInteger("deptId", Integer.valueOf(deptId));
		List<User> users = query.getResultList();
		return users;
	}	
	@RequestMapping(value="getDeptsUsers" )
	public @ResponseBody List<User> getDeptsUsers(String deptIds) throws JsonProcessingException, IOException{
		String[] depts=deptIds.split(",");
		List list=new ArrayList<User>();
		for(String deptId:depts)
		{
			String hql="from User where deptId=:deptId";
			Query  query = this.getCurrentSession().createQuery(hql, User.class).setCacheable(true);
			query.setInteger("deptId", Integer.valueOf(deptId));
			List<User> users = query.getResultList();
			list.addAll(users);
			
		}
		return list;
	}	
	@RequestMapping("page_data")
	public @ResponseBody PageData getPagedata(Integer page, Integer rows, String filter) {
		//应该取出的是本级人行的管理员、操作员、本级所属金融机构的操作员，及下级的管理员
		PageData grid_data = new PageData();
		if (filter == null)
			filter = "";
		User op = operator.getUser();
		if (op == null)
			return grid_data;
		
		String pbcid = op.getJgId();
		String pbcidlist = getPbcChildren(pbcid);
		
		String wherestr = "where (jgId='" + pbcid + "' or (jgId in(" + pbcidlist + ") and roleId='001')  )"
				+ filter;

		Long total = this.getCurrentSession().createQuery("select count(1) from User " + wherestr , Long.class)
				.getSingleResult();
		Query<User> q = this.getCurrentSession().createQuery("from User  " + wherestr +"  order by jgId asc", User.class)
				.setCacheable(true);
		q.setFirstResult((page - 1) * rows).setMaxResults(rows);
		List<User> users = q.getResultList();
		grid_data.setValue(total.intValue(), users);
		return grid_data;
	}

	private boolean exist(User op) {
		List<User> Users = this.getCurrentSession()
				.createQuery("from User where code='" + op.getCode() + "'", User.class).getResultList();
		if(Users.size()>1) return true;
		if(op.getId()==null && Users.size()>0) return true;
		for(User User:Users){
			if(op.getId()!=User.getId()) return true;
			this.getCurrentSession().evict(User);//解决 A different object with the same identifier value was already associated with the session
		}
		return false;
	}

	@RequestMapping("save")
	public @ResponseBody Result save(User op, boolean setpass) {
		Result result = new Result();
		//存在是指，新增用户，代码已经占用；已存在用户修改代码，该代码已经被占用
		if (exist(op)) {
			result.setValue(1, "该用户代码已经被使用！");
			return result;
		}
		op.setPassword("123456");
		userService.saveOrUpdate(op);
		result.setData(op);
		result.setValue(0, "用户保存成功！");
		return result;
	}
	@RequestMapping("edit")
	public @ResponseBody Result edit(String id,String emailAddress,String emailPassword,String name, boolean setpass) {
		Result result = new Result();
		User op=userService.get(Integer.valueOf(id));
		op.setEmailAddress(emailAddress);
		op.setEmailPassword(emailPassword);
		op.setName(name);
		if (setpass) {
			op.setPassword("123456");
		}
		userService.saveOrUpdate(op);
		//如果修改了自己，那么要刷新session
		if(operator.getUser().getCode().equals(op.getClass()))
			operator.setUser(op);
		result.setData(op);
		result.setValue(0, "用户保存成功！");
		return result;
	}
	@RequestMapping("delete")
	public @ResponseBody Result delete(Integer id) {
		Result result = new Result();
		User tmp = userService.get(id);
		userService.delete(tmp);
		result.setValue(0, "删除成功");
		return result;
	}
	
	@RequestMapping("chgpass")
	public @ResponseBody Result chgpass(String password0, String password1, String password2) {
		Result result = new Result();
		User op = operator.getUser();
		if (op == null) {
			result.setValue(1, "尚未登录");
			return result;
		}
		if (!op.getPassword().equals(password0)) {
			result.setValue(1, "密码错误");
			return result;
		}
		if (!password1.equals(password2)) {
			result.setValue(1, "新密码前后不一致");
			return result;
		}
		op.setPassword(password1);
		userService.saveOrUpdate(op);
		result.setValue(0, "密码修改成功");
		return result;
	}
	@RequestMapping("/getLoginUser")
	public @ResponseBody User getLoginUser() {
		 
		return operator.getUser();
	}
}
